#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2020-present Batocera
# Copyright (C) 2020-present Fewtarius

#
# Download and install packages supported binary packages
#
# Usage:
# amberelec-es-package 'list' or 'install <package>'
#
# If you don't provide a <package>, the list of packages will be downloaded and sent back to you.
#

ARCH="$(cat /storage/.config/.OS_ARCH)"
if [ "${ARCH}" == "RG351P" ]; then
  DEVICE="RG351P"
elif [ "${ARCH}" == "RG351V" ]; then
  DEVICE="RG351V"
elif [ "${ARCH}" == "RG351MP" ]; then
  DEVICE="RG351MP"
elif [ "${ARCH}" == "RG552" ]; then
  DEVICE="RG552"
fi
DISTRO="AmberELEC"
CONFIGDIR="/storage/.config/packages"
PACKAGELIST="https://raw.githubusercontent.com/AmberELEC/metadata/main/${ARCH}/packages.cfg"
LOCALPACKAGELIST="/storage/.config/packages.cfg"

# Community Package List Schema
#
# {PACKAGE NAME}|{PACKAGE URL}|{SHA256SUM}
#
# Half_Life|https://github.com/blah/half-life-1231.zip|d06489dcf04c602ddacc6f80b2809e6d25fd6298c461966e666e19d3188e04be
#
# packages.cfg must be a plain text pipe delimited file.

# Community Package Schema
#
# URL: https://github.com/blah/half-life-1231.zip
# Content:
# half-life/ <- must match "package" name ^
#           install.sh <- must be named install.sh/uninstall.sh and be in the package root.
#           uninstall.sh
#           Relevant files/directories included in install.sh/uninstall.sh
#           Minimum:
#                    system-half-life.png
#                    system-half-life-thumb.png
#
# The package blob may be hosted elsewhere, as long as install.sh is able to download it.

###############################
#
# Prepare the system for installation
if [ ! -d "${CONFIGDIR}" ]
then
  mkdir -p "${CONFIGDIR}"
fi

###############################
#
function usage() {
	echo "$0 - downloads and installs packages supported packages in ${DISTRO}"
	echo " "
	echo "It accepts two modes: 'list' and 'install <package>'"
	echo "- 'list' for the list of packages available online, and if they are"
	echo "   [A]vailable to install, [I]nstalled or [?]unknown."
	echo "- 'install <package>' to install the package, from its package name."
	echo "- 'remove <package>' to delete an installed package."
	echo " "
	exit 1
}

###############################
#
function check_url() {
	[[ "$1" =~ ^(https?|ftp)://.*$ ]] && echo "[A]" || echo "[?]"
}

###############################
#
function git_name() {
	echo "$1" | sed "s,.*/\(.*\),\1,"
}

###############################
#
function repo_name() {
	echo "$1" | sed "s,.*github.com/\([A-Za-z0-9_-]*\)/.*,\1,"
}

###############################
#
function list_packages() {
	fn=$(date +"%s")
	tmp="/tmp/packages_${fn}"
	echo "* ${DISTRO} packages *"
	if [ -f ${LOCALPACKAGELIST} ]; then
		cp -f "${LOCALPACKAGELIST}" "${tmp}"
	else
		curl -H 'Cache-Control: no-cache' -sfL "${PACKAGELIST}" -o "${tmp}" || exit 1
		sed -i 's/\r$//' "${tmp}"
	fi
	while IFS=$'|' read name url shasum; do
		[ x"${name}" == "x" ] && continue
		ia=$(check_url "${url}")
		[ -d "${CONFIGDIR}"/"${name}" ] && ia="[I]"
		echo "${ia} ${name} - ${url}"
	done < "${tmp}"
	[[ -e "${tmp}" ]] && rm "${tmp}"
}


###############################
#
function getPer() {
	TARFILE="$1"
	TARVAL="$2"
	while true; do
		CURVAL=$(stat "$TARFILE" | grep -E '^[ ]*Size:' | sed -e s+'^[ ]*Size: \([0-9][0-9]*\) .*$'+'\1'+)
		CURVAL=$((CURVAL / 1024 / 1024))
		PER=$((${CURVAL} * 100 / ${TARVAL}))
		echo "${PER}% - ${package} - [${TARVAL}MB]"
		sleep 2
	done
}

###############################
#
function install_package() {
	package="$1"
	success_installed=0
	fn=$(date +"%s")
	tmp="/tmp/packages_${fn}"
	if [ -f ${LOCALPACKAGELIST} ]; then
		cp -f "${LOCALPACKAGELIST}" "${tmp}"
	else
		curl -H 'Cache-Control: no-cache' -sfL "${PACKAGELIST}" -o "${tmp}" || exit 1
		sed -i 's/\r$//' "${tmp}"
	fi
	while IFS=$'|' read name url shasum; do
		[ x"${name}" != x"${package}" ] && continue
		ia=$(check_url "${url}")
		if [ x"${ia}" != x"[A]" ]; then
			echo "Error - invalid package URL ${url}"
			exit 1
		else
			cd ${CONFIGDIR}
			filename=$(echo ${url} | sed "s#^.*/##")
			curl -H 'Cache-Control: no-cache' -sfL "${url}" -o "${filename}" || exit 1
			if [ -f "${filename}" ]; then
				echo "Verifying package checksum"
				dldsum=$(sha256sum ${filename} | awk '{print $1}')
				if [ ! "${shasum}" == "${dldsum}" ]
				then
				  echo "Error - Checksum does not match."
				  success_installed=0
				else
				  echo "Unzipping ${filename} package files >>> 99%"
				  if [ -d "${CONFIGDIR}/${filename}" ]
				  then
				    rm -rf "${CONFIGDIR}/${filename}"
				  fi
				  unzip "${filename}" >/dev/null 2>&1
				  rm "${filename}"
				  echo "Installing ${filename} package"
				  sh ./${package}/install.sh
				  if [ $? == 0 ]
				  then
				    success_installed=1
				  else
				    echo "Error - Installation failed."
				    success_installed=0
				  fi
				fi
			else
				echo "Error - ${package} zip file could not be downloaded from ${url}"
				exit 1
			fi
		fi
	done < "${tmp}"
	[[ -e "${tmp}" ]] && rm "${tmp}"
	if [ "${success_installed}" == 1 ]; then
		echo "${package} is now installed >>> 100%"
		exit 0
	else
		echo "Error - ${package} could not be installed"
		exit 1
	fi
}

###############################
#
function remove_package() {
	package="$1"
	success_removed=0
		filename=${package}
		if [ -d "${CONFIGDIR}/${package}" ]; then
			sh ${CONFIGDIR}/${package}/uninstall.sh
			if [ $? == 0 ]
			then
		       	  rm -rf "${CONFIGDIR}"/"${filename}" && success_removed=1
			else
			  echo "Unable to uninstall ${package}"
			  success_removed=0
			fi
		else
			echo "${package} doesn't appear to be in ${CONFIGDIR}/${filename}"
		fi
	if [ "${success_removed}" == 1 ]; then
		TERMINAL=0 && echo "${package} uninstalled >>>100"
		exit 0
	else
		echo "Error - ${package} could not be removed"
		exit 1
	fi
}

#### Main loop
#
command="$1"
package="$2"

if ! [ -d "${CONFIGDIR}" ]; then
	echo "Error - package directory ${CONFIGDIR} is not valid."
	exit 1
fi
if [ x"${command}" == "xlist" ]; then
	list_packages
elif [ x"${command}" == "xinstall" ]; then
	[ x"${package}" != "x" ] && install_package ${package} || usage
elif [ x"${command}" == "xremove" ]; then
	[ x"${package}" != "x" ] && remove_package ${package} || usage
else
	usage
fi
